#include "defines.h"


int main(int argc, char * argv[]) {

	struct timeval start, end;

	long int t, i, j, x, y;
	int NX = atoi(argv[1]);
	int NY = atoi(argv[2]);
	int T  = atoi(argv[3]);

	DATA_TYPE (*A)[NX+2*XSTART][NY+2*YSTART] = (DATA_TYPE (*)[NX+2*XSTART][NY+2*YSTART])malloc(sizeof(DATA_TYPE)*(NX+2*XSTART)*(NY+2*YSTART)*2);
	if(NULL == A) return 0;

#ifdef CHECK
	DATA_TYPE (*B)[NX+2*XSTART][NY+2*YSTART] = (DATA_TYPE (*)[NX+2*XSTART][NY+2*YSTART])malloc(sizeof(DATA_TYPE)*(NX+2*XSTART)*(NY+2*YSTART)*2);
	if(NULL == B) return 0;
#endif

	srand(100);

	for (i = 0; i < NX+2*XSTART; i++) {
		for (j = 0; j < NY+2*YSTART; j++) {
			A[0][i][j] = (DATA_TYPE) (1.0 * (rand() % 1024));
			A[1][i][j] = A[0][i][j];
#ifdef CHECK
			B[0][i][j] = A[0][i][j];
			B[1][i][j] = A[0][i][j];
#endif
		}
	}


	gettimeofday(&start,0);
	for (t = 0; t < T; t++) {
		#pragma omp parallel for collapse(2)
		for (x = XSTART; x < NX + XSTART; x++) {
			for (y = YSTART; y < NY + YSTART; y++) {
				kernel(A);
			}
		}
	}	gettimeofday(&end,0);

	printf("GStencil/s = %f\n", ((double)NX * NY * T) / (double)(end.tv_sec - start.tv_sec + (end.tv_usec - start.tv_usec) * 1.0e-6) / 1000000000L);

#ifdef CHECK
	for (t = 0; t < T; t++) {
		for (x = XSTART; x < NX + XSTART; x++) {
			for (y = YSTART; y < NY + YSTART; y++) {
				kernel(B);
			}
		}
	}
	for (i = XSTART; i < NX+XSTART; i++) {
		for (j = YSTART; j < NY+YSTART; j++) {
			if(A[T%2][i][j] != B[T%2][i][j])
				printf("correct[%d][%d] = %f, wrong = %f: FAILED!\n", i, j, B[T%2][i][j], A[T%2][i][j]);
			}
	}
#endif
}
